export const isMobile = (s: string): boolean => {
	return /^1[0-9]{10}$/.test(s);
};

export const isPhone = (s: string): boolean => {
	return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s);
};

export const isURL = (s: string): boolean => {
	return /^http[s]?:\/\/.*/.test(s);
};

export const check = (s: string, type: string): boolean => {
	switch (type) {
		case 'Phone': //手机号码
			return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(s);
		case 'Tel': //座机
			return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(s);
		case 'Card': //身份证
			return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(s);
		case 'Password': //密码以字母开头，长度在6~18之间，只能包含字母、数字和下划线
			return /^[a-zA-Z]\w{5,17}$/.test(s);
		case 'Postal': //邮政编码
			return /[1-9]\d{5}(?!\d)/.test(s);
		case 'QQ': //QQ号
			return /^[1-9][0-9]{4,9}$/.test(s);
		case 'Email': //邮箱
			return /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(s);
		case 'Money': //金额(小数点2位)
			return /^\d*(?:\.\d{0,2})?$/.test(s);
		case 'URL': //网址
			return /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/.test(
				s
			);
		case 'IP': //IP
			return /((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))/.test(
				s
			);
		case 'Date': //日期时间
			return (
				/^(\d{4})-(\d{2})-(\d{2}) (\d{2})(?::\d{2}|:(\d{2}):(\d{2}))$/.test(
					s
				) || /^(\d{4})-(\d{2})-(\d{2})$/.test(s)
			);
		case 'Number': //数字
			return /^[0-9]$/.test(s);
		case 'English': //英文
			return /^[a-zA-Z]+$/.test(s);
		case 'Chinese': //中文
			return /^[\\u4E00-\\u9FA5]+$/.test(s);
		case 'Lower': //小写
			return /^[a-z]+$/.test(s);
		case 'Upper': //大写
			return /^[A-Z]+$/.test(s);
		case 'HTML': //HTML标记
			return /<("[^"]*"|'[^']*'|[^'">])*>/.test(s);
		default:
			return true;
	}
};

export const isCardID = (id: string): boolean => {
	if (!/(^\d{15}$)|(^\d{17}(\d|X|x)$)/.test(id)) {
		console.log('你输入的身份证长度或格式错误');
		return false;
	}
	//身份证城市
	const cities = {
		11: '北京',
		12: '天津',
		13: '河北',
		14: '山西',
		15: '内蒙古',
		21: '辽宁',
		22: '吉林',
		23: '黑龙江',
		31: '上海',
		32: '江苏',
		33: '浙江',
		34: '安徽',
		35: '福建',
		36: '江西',
		37: '山东',
		41: '河南',
		42: '湖北',
		43: '湖南',
		44: '广东',
		45: '广西',
		46: '海南',
		50: '重庆',
		51: '四川',
		52: '贵州',
		53: '云南',
		54: '西藏',
		61: '陕西',
		62: '甘肃',
		63: '青海',
		64: '宁夏',
		65: '新疆',
		71: '台湾',
		81: '香港',
		82: '澳门',
		91: '国外',
	};
	if (!cities[parseInt(id.substr(0, 2))]) {
		console.log('你的身份证地区非法');
		return false;
	}
	// 出生日期验证
	const birthday = `${id.substr(6, 4)}/${Number(id.substr(10, 2))}/${Number(
		id.substr(12, 2)
	)}`;
	const date = new Date(birthday);
	if (
		birthday !==
		`${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`
	) {
		console.log('身份证上的出生日期非法');
		return false;
	}
	// 身份证号码校验
	const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
	const codes = '10X98765432';
	let sum = 0;
	for (let i = 0; i < id.length - 1; i++) {
		sum += Number(id[i]) * weights[i];
	}
	const last = codes[sum % 11]; //计算出来的最后一位身份证号码
	if (id[id.length - 1] !== String(last)) {
		console.log('你输入的身份证号非法');
		return false;
	}
	return true;
};

export const isString = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'String';
};

export const isNumber = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Number';
};

export const isBoolean = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Boolean';
};

export const isFunction = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Function';
};

export const isNull = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Null';
};

export const isUndefined = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Undefined';
};

export const isObject = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Object';
};

export const isArray = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Array';
};

export const isDate = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Date';
};

export const isRegExp = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'RegExp';
};

export const isError = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Error';
};

export const isSymbol = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Symbol';
};

export const isPromise = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Promise';
};

export const isSet = (o: unknown): boolean => {
	return Object.prototype.toString.call(o).slice(8, -1) === 'Set';
};

export const userAgent = (): string => navigator.userAgent;

export const isWeiXin = (): boolean => {
	return (
		(userAgent()
			.toLowerCase()
			.match(/microMessenger/i) as unknown) === 'micromessenger'
	);
};

export const isDeviceMobile = (): boolean => {
	return /android|webos|iphone|ipod|balckberry/i.test(
		userAgent().toLowerCase()
	);
};

export const isQQBrowser = (): boolean => {
	return !!userAgent()
		.toLowerCase()
		.match(/mqqbrowser|qzone|qqbrowser|qbwebviewtype/i);
};

export const isSpider = (): boolean => {
	return /adsbot|googlebot|bingbot|msnbot|yandexbot|baidubot|robot|careerbot|seznambot|bot|baiduspider|jikespider|symantecspider|scannerlwebcrawler|crawler|360spider|sosospider|sogou web sprider|sogou orion spider/.test(
		userAgent().toLowerCase()
	);
};

export const isIos = (): boolean => {
	const ua = userAgent();
	if (ua.indexOf('Android') > -1 || ua.indexOf('Linux') > -1) {
		//安卓手机
		return false;
	} else if (ua.indexOf('iPhone') > -1) {
		//苹果手机
		return true;
	} else if (ua.indexOf('iPad') > -1) {
		//iPad
		return false;
	} else if (ua.indexOf('Windows Phone') > -1) {
		//winphone手机
		return false;
	} else {
		return false;
	}
};

export const isPC = (): boolean => {
	const ua = userAgent();
	const Agents = [
		'Android',
		'iPhone',
		'SymbianOS',
		'Windows Phone',
		'iPad',
		'iPod',
	];
	let flag = true;
	for (let v = 0; v < Agents.length; v++) {
		if (ua.indexOf(Agents[v]) > 0) {
			flag = false;
			break;
		}
	}
	return flag;
};

export const removeHtmltag = (s: string): string => {
	return s.replace(/<[^>]+>/g, '');
};

// export const injectScript = (src: string): void => {
// 	const s = document.createElement('script');
// 	s.type = 'text/javascript';
// 	s.async = true;
// 	s.src = src;
// 	const t = document.getElementsByTagName('script')[0];
// 	t.parentNode?.insertBefore(s, t);
// };

export const download = (url: string): boolean => {
	const isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
	const isSafari = navigator.userAgent.toLowerCase().indexOf('safari') > -1;
	if (isChrome || isSafari) {
		const link = document.createElement('a');
		link.href = url;
		if (link.download !== undefined) {
			link.download = url.substring(url.lastIndexOf('/') + 1, url.length);
		}
		if (document.createEvent) {
			const e = document.createEvent('MouseEvents');
			e.initEvent('click', true, true);
			link.dispatchEvent(e);
			return true;
		}
	}
	if (url.indexOf('?') === -1) {
		url += '?download';
	}
	window.open(url, '_self');
	return true;
};

export const hasClass = (el: Element, className: string): boolean => {
	const reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
	return reg.test(el.className);
};

export const addClass = (el: Element, className: string): void => {
	if (!hasClass(el, className)) {
		const newClasses = el.className.split(' ');
		newClasses.push(className);
		el.className = newClasses.join(' ');
	}
};

export const removeClass = (el: Element, className: string): void => {
	if (hasClass(el, className)) {
		const reg = new RegExp('(^|\\s)' + className + '(\\s|$)', 'g');
		el.className = el.className.replace(reg, ' ');
	}
};

export const getPageScroll = (): {
	x: number;
	y: number;
} => ({
	x: window.pageXOffset,
	y: window.pageYOffset,
});

export const getElementScroll = (
	el: Element
): {
	x: number;
	y: number;
} => ({
	x: el.scrollLeft,
	y: el.scrollTop,
});

export const scrollToTop = (): void => {
	const c = document.documentElement.scrollTop || document.body.scrollTop;
	if (c > 0) {
		window.requestAnimationFrame(scrollToTop);
		window.scrollTo(0, c - c / 8);
	}
};

export const elementIsVisibleInViewport = (
	el: Element,
	partiallyVisible = false
): boolean => {
	const { top, left, bottom, right } = el.getBoundingClientRect();
	const { innerHeight, innerWidth } = window;
	return partiallyVisible
		? ((top > 0 && top < innerHeight) ||
				(bottom > 0 && bottom < innerHeight)) &&
				((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
		: top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};

export const copyTextToClipboard = (s: string): void => {
	const textArea = document.createElement('textarea');
	textArea.style.background = 'transparent';
	textArea.value = s;
	document.body.appendChild(textArea);
	textArea.select();
	try {
		document.execCommand('copy');
	} catch (err) {
		console.log('Oops, unable to copy');
	}
	document.body.removeChild(textArea);
};
